package com.fan.tank;

import com.fan.common.Audio;
import com.fan.common.ResourceMgr;
import com.fan.design_pattern.decorator.RectDecorator;
import com.fan.design_pattern.decorator.TailDecorator;
import com.fan.frame.TankFrame;
import com.fan.tank.GameModel.GameModel;
import com.fan.tank.GameObject.GameObject;
import com.fan.util.Dir;
import com.fan.util.TankGroup;

import java.awt.*;
import java.util.Random;

/**
 * 坦克封装
 * @Author: fan
 * @DateTime: 2021-03-26 15:46
 **/
public class Tank extends GameObject {
//    public int x, y;
    int oldX, oldY;
    public  Dir dir = Dir.DOWN;
    private static final int SPEED = 5;
    public static int WIDTH = ResourceMgr.goodTankD.getWidth();
    public static int HEIGHT = ResourceMgr.goodTankD.getHeight();

    private Random random = new Random();


    public TankGroup tankGroup = TankGroup.BadTank;
    public Rectangle rectangle = new Rectangle();

    // 判断坦克是否移动
    private boolean moving = true;

    // 坦克存活状态
    private boolean living = true;

    // 判断坦克类型
//    public TankGroup tankGroup = TankGroup.BadTank;

//    public Rectangle rectangle = new Rectangle();


    public Tank(int x, int y, Dir dir, TankGroup tankGroup) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        this.tankGroup = tankGroup;

        rectangle.x = this.x;
        rectangle.y = this.y;
        rectangle.width = WIDTH;
        rectangle.height = HEIGHT;

        GameModel.getInstance().add(this);
    }

    /**
     * 坦克绘制
     * @param g
     */
    @Override
    public void paint(Graphics g) {
        if(!living) {
            GameModel.getInstance().remove(this);
        }
        switch (dir) {
            case LEFT:
                g.drawImage(this.tankGroup == TankGroup.GoodTank ? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null);
                break;
            case UP:
                g.drawImage(this.tankGroup == TankGroup.GoodTank ? ResourceMgr.goodTankU : ResourceMgr.badTankU, x, y, null);
                break;
            case RIGHT:
                g.drawImage(this.tankGroup == TankGroup.GoodTank ? ResourceMgr.goodTankR : ResourceMgr.badTankR, x, y, null);
                break;
            case DOWN:
                g.drawImage(this.tankGroup == TankGroup.GoodTank ? ResourceMgr.goodTankD : ResourceMgr.badTankD, x, y, null);
                break;
            default:
                break;
        }

        move();
    }

    /**
     * 回到上一步的位置
     */
    public void back() {
        x = oldX;
        y = oldY;
    }

    /**
     * 方向控制
     */
    private void move() {
        // 记录移动之前的位置
        oldX = x;
        oldY = y;

        if (!moving) {
            return;
        }
        switch (dir) {
            case LEFT:
                x -= SPEED;
                break;
            case UP:
                y -= SPEED;
                break;
            case RIGHT:
                x += SPEED;
                break;
            case DOWN:
                y += SPEED;
                break;
            default:
                break;
        }

        if (this.tankGroup == TankGroup.BadTank && random.nextInt(100) > 95 ) {
            this.fire();
        }

        if(this.tankGroup == TankGroup.BadTank && random.nextInt(100) > 95) {
            this.randomDir();
        }

        boundsCheck();

        // 更新rectangle
        rectangle.x = this.x;
        rectangle.y = this.y;
    }

    /**
     * 边界检测
     */
    private void boundsCheck() {
        if(this.x < 0) {
            x = 2;
        }
        if(this.y < 28) {
            y = 28;
        }
        if(this.x > TankFrame.GAME_WIDTH - Tank.WIDTH - 2) {
            x = TankFrame.GAME_WIDTH - Tank.WIDTH - 2;
        }
        if(this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2) {
            y = TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2;
        }
    }

    /**
     * 随机方向
     */
    private void randomDir() {
        this.dir = Dir.values()[random.nextInt(4)];
    }

    /**
     * 生成子弹
     */
    public void fire() {
        int bulletX = this.x + Tank.WIDTH / 2 - Bullet.WIDTH / 2;
        int bulletY = this.y + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2;
        Dir[] dirs = Dir.values();

        if (this.tankGroup == TankGroup.GoodTank) {
            for (Dir dir : dirs) {
                GameModel.getInstance().add(new Bullet(bulletX, bulletY, dir, this.tankGroup));
//                GameModel.getInstance().add(new RectDecorator(new Bullet(bulletX, bulletY, dir, this.tankGroup)));
            }
            new Thread(() -> new Audio("audio/tank_fire.wav").play()).start();
        }else {
            GameModel.getInstance().add(new Bullet(bulletX, bulletY, dir, this.tankGroup));
            // 装饰器模式可以给坦克、子弹等添加自定义的装饰
//            GameModel.getInstance().add( new RectDecorator(new Bullet(bulletX, bulletY, dir, this.tankGroup)));
            // 装饰器之间可以混合使用
//            GameModel.getInstance().add( new RectDecorator(new TailDecorator(new Bullet(bulletX, bulletY, dir, this.tankGroup))));
        }
    }

    @Override
    public int getWidth() {
        return WIDTH;
    }

    @Override
    public int getHeight() {
        return HEIGHT;
    }

    /**
     * 坦克消失
     */
    public void die() {
        this.living = false;
    }

    /**
     * 坦克停止
     */
    public void stop () {
        moving = false;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Dir getDir() {
        return dir;
    }

    public void setDir(Dir dir) {
        this.dir = dir;
    }

    public boolean isMoving() {
        return moving;
    }

    public void setMoving(boolean moving) {
        this.moving = moving;
    }

    public TankGroup getTankGroup() {
        return tankGroup;
    }

    public void setTankGroup(TankGroup tankGroup) {
        this.tankGroup = tankGroup;
    }

    public Rectangle getRectangle() {
        return rectangle;
    }
}
